{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "## 乳腺癌的预测"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "source": [
    "import torch\r\n",
    "print(torch.__version__)"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "1.9.0\n"
     ]
    }
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "---"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 介绍"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "上一个试验我们讲解了线性问题的求解步骤，本实验我们以乳腺癌的预测为实例，详细的阐述如何利用 PyTorch 求解一个非线性问题。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 知识点"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "- 数据集的标准化\n",
    "- 数据集的划分\n",
    "- Sigmoid 函数\n",
    "- 乳腺癌的预测"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "---"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 数据集的预处理"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 数据集的加载"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "首先，让我们来加载数据集合。这里我们使用 `pandas` 对数据集合进行加载："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "source": [
    "import pandas as pd\r\n",
    "df = pd.read_csv(\r\n",
    "    'https://labfile.oss.aliyuncs.com/courses/2534/breast_cancer.csv', index_col=False)\r\n",
    "df"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "     mean radius  mean texture  mean perimeter  mean area  mean smoothness  \\\n",
       "0          17.99         10.38          122.80     1001.0          0.11840   \n",
       "1          20.57         17.77          132.90     1326.0          0.08474   \n",
       "2          19.69         21.25          130.00     1203.0          0.10960   \n",
       "3          11.42         20.38           77.58      386.1          0.14250   \n",
       "4          20.29         14.34          135.10     1297.0          0.10030   \n",
       "..           ...           ...             ...        ...              ...   \n",
       "564        21.56         22.39          142.00     1479.0          0.11100   \n",
       "565        20.13         28.25          131.20     1261.0          0.09780   \n",
       "566        16.60         28.08          108.30      858.1          0.08455   \n",
       "567        20.60         29.33          140.10     1265.0          0.11780   \n",
       "568         7.76         24.54           47.92      181.0          0.05263   \n",
       "\n",
       "     mean compactness  mean concavity  mean concave points  mean symmetry  \\\n",
       "0             0.27760         0.30010              0.14710         0.2419   \n",
       "1             0.07864         0.08690              0.07017         0.1812   \n",
       "2             0.15990         0.19740              0.12790         0.2069   \n",
       "3             0.28390         0.24140              0.10520         0.2597   \n",
       "4             0.13280         0.19800              0.10430         0.1809   \n",
       "..                ...             ...                  ...            ...   \n",
       "564           0.11590         0.24390              0.13890         0.1726   \n",
       "565           0.10340         0.14400              0.09791         0.1752   \n",
       "566           0.10230         0.09251              0.05302         0.1590   \n",
       "567           0.27700         0.35140              0.15200         0.2397   \n",
       "568           0.04362         0.00000              0.00000         0.1587   \n",
       "\n",
       "     mean fractal dimension  ...  worst texture  worst perimeter  worst area  \\\n",
       "0                   0.07871  ...          17.33           184.60      2019.0   \n",
       "1                   0.05667  ...          23.41           158.80      1956.0   \n",
       "2                   0.05999  ...          25.53           152.50      1709.0   \n",
       "3                   0.09744  ...          26.50            98.87       567.7   \n",
       "4                   0.05883  ...          16.67           152.20      1575.0   \n",
       "..                      ...  ...            ...              ...         ...   \n",
       "564                 0.05623  ...          26.40           166.10      2027.0   \n",
       "565                 0.05533  ...          38.25           155.00      1731.0   \n",
       "566                 0.05648  ...          34.12           126.70      1124.0   \n",
       "567                 0.07016  ...          39.42           184.60      1821.0   \n",
       "568                 0.05884  ...          30.37            59.16       268.6   \n",
       "\n",
       "     worst smoothness  worst compactness  worst concavity  \\\n",
       "0             0.16220            0.66560           0.7119   \n",
       "1             0.12380            0.18660           0.2416   \n",
       "2             0.14440            0.42450           0.4504   \n",
       "3             0.20980            0.86630           0.6869   \n",
       "4             0.13740            0.20500           0.4000   \n",
       "..                ...                ...              ...   \n",
       "564           0.14100            0.21130           0.4107   \n",
       "565           0.11660            0.19220           0.3215   \n",
       "566           0.11390            0.30940           0.3403   \n",
       "567           0.16500            0.86810           0.9387   \n",
       "568           0.08996            0.06444           0.0000   \n",
       "\n",
       "     worst concave points  worst symmetry  worst fractal dimension  target  \n",
       "0                  0.2654          0.4601                  0.11890       0  \n",
       "1                  0.1860          0.2750                  0.08902       0  \n",
       "2                  0.2430          0.3613                  0.08758       0  \n",
       "3                  0.2575          0.6638                  0.17300       0  \n",
       "4                  0.1625          0.2364                  0.07678       0  \n",
       "..                    ...             ...                      ...     ...  \n",
       "564                0.2216          0.2060                  0.07115       0  \n",
       "565                0.1628          0.2572                  0.06637       0  \n",
       "566                0.1418          0.2218                  0.07820       0  \n",
       "567                0.2650          0.4087                  0.12400       0  \n",
       "568                0.0000          0.2871                  0.07039       1  \n",
       "\n",
       "[569 rows x 31 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mean radius</th>\n",
       "      <th>mean texture</th>\n",
       "      <th>mean perimeter</th>\n",
       "      <th>mean area</th>\n",
       "      <th>mean smoothness</th>\n",
       "      <th>mean compactness</th>\n",
       "      <th>mean concavity</th>\n",
       "      <th>mean concave points</th>\n",
       "      <th>mean symmetry</th>\n",
       "      <th>mean fractal dimension</th>\n",
       "      <th>...</th>\n",
       "      <th>worst texture</th>\n",
       "      <th>worst perimeter</th>\n",
       "      <th>worst area</th>\n",
       "      <th>worst smoothness</th>\n",
       "      <th>worst compactness</th>\n",
       "      <th>worst concavity</th>\n",
       "      <th>worst concave points</th>\n",
       "      <th>worst symmetry</th>\n",
       "      <th>worst fractal dimension</th>\n",
       "      <th>target</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>17.99</td>\n",
       "      <td>10.38</td>\n",
       "      <td>122.80</td>\n",
       "      <td>1001.0</td>\n",
       "      <td>0.11840</td>\n",
       "      <td>0.27760</td>\n",
       "      <td>0.30010</td>\n",
       "      <td>0.14710</td>\n",
       "      <td>0.2419</td>\n",
       "      <td>0.07871</td>\n",
       "      <td>...</td>\n",
       "      <td>17.33</td>\n",
       "      <td>184.60</td>\n",
       "      <td>2019.0</td>\n",
       "      <td>0.16220</td>\n",
       "      <td>0.66560</td>\n",
       "      <td>0.7119</td>\n",
       "      <td>0.2654</td>\n",
       "      <td>0.4601</td>\n",
       "      <td>0.11890</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20.57</td>\n",
       "      <td>17.77</td>\n",
       "      <td>132.90</td>\n",
       "      <td>1326.0</td>\n",
       "      <td>0.08474</td>\n",
       "      <td>0.07864</td>\n",
       "      <td>0.08690</td>\n",
       "      <td>0.07017</td>\n",
       "      <td>0.1812</td>\n",
       "      <td>0.05667</td>\n",
       "      <td>...</td>\n",
       "      <td>23.41</td>\n",
       "      <td>158.80</td>\n",
       "      <td>1956.0</td>\n",
       "      <td>0.12380</td>\n",
       "      <td>0.18660</td>\n",
       "      <td>0.2416</td>\n",
       "      <td>0.1860</td>\n",
       "      <td>0.2750</td>\n",
       "      <td>0.08902</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>19.69</td>\n",
       "      <td>21.25</td>\n",
       "      <td>130.00</td>\n",
       "      <td>1203.0</td>\n",
       "      <td>0.10960</td>\n",
       "      <td>0.15990</td>\n",
       "      <td>0.19740</td>\n",
       "      <td>0.12790</td>\n",
       "      <td>0.2069</td>\n",
       "      <td>0.05999</td>\n",
       "      <td>...</td>\n",
       "      <td>25.53</td>\n",
       "      <td>152.50</td>\n",
       "      <td>1709.0</td>\n",
       "      <td>0.14440</td>\n",
       "      <td>0.42450</td>\n",
       "      <td>0.4504</td>\n",
       "      <td>0.2430</td>\n",
       "      <td>0.3613</td>\n",
       "      <td>0.08758</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>11.42</td>\n",
       "      <td>20.38</td>\n",
       "      <td>77.58</td>\n",
       "      <td>386.1</td>\n",
       "      <td>0.14250</td>\n",
       "      <td>0.28390</td>\n",
       "      <td>0.24140</td>\n",
       "      <td>0.10520</td>\n",
       "      <td>0.2597</td>\n",
       "      <td>0.09744</td>\n",
       "      <td>...</td>\n",
       "      <td>26.50</td>\n",
       "      <td>98.87</td>\n",
       "      <td>567.7</td>\n",
       "      <td>0.20980</td>\n",
       "      <td>0.86630</td>\n",
       "      <td>0.6869</td>\n",
       "      <td>0.2575</td>\n",
       "      <td>0.6638</td>\n",
       "      <td>0.17300</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20.29</td>\n",
       "      <td>14.34</td>\n",
       "      <td>135.10</td>\n",
       "      <td>1297.0</td>\n",
       "      <td>0.10030</td>\n",
       "      <td>0.13280</td>\n",
       "      <td>0.19800</td>\n",
       "      <td>0.10430</td>\n",
       "      <td>0.1809</td>\n",
       "      <td>0.05883</td>\n",
       "      <td>...</td>\n",
       "      <td>16.67</td>\n",
       "      <td>152.20</td>\n",
       "      <td>1575.0</td>\n",
       "      <td>0.13740</td>\n",
       "      <td>0.20500</td>\n",
       "      <td>0.4000</td>\n",
       "      <td>0.1625</td>\n",
       "      <td>0.2364</td>\n",
       "      <td>0.07678</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>564</th>\n",
       "      <td>21.56</td>\n",
       "      <td>22.39</td>\n",
       "      <td>142.00</td>\n",
       "      <td>1479.0</td>\n",
       "      <td>0.11100</td>\n",
       "      <td>0.11590</td>\n",
       "      <td>0.24390</td>\n",
       "      <td>0.13890</td>\n",
       "      <td>0.1726</td>\n",
       "      <td>0.05623</td>\n",
       "      <td>...</td>\n",
       "      <td>26.40</td>\n",
       "      <td>166.10</td>\n",
       "      <td>2027.0</td>\n",
       "      <td>0.14100</td>\n",
       "      <td>0.21130</td>\n",
       "      <td>0.4107</td>\n",
       "      <td>0.2216</td>\n",
       "      <td>0.2060</td>\n",
       "      <td>0.07115</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>565</th>\n",
       "      <td>20.13</td>\n",
       "      <td>28.25</td>\n",
       "      <td>131.20</td>\n",
       "      <td>1261.0</td>\n",
       "      <td>0.09780</td>\n",
       "      <td>0.10340</td>\n",
       "      <td>0.14400</td>\n",
       "      <td>0.09791</td>\n",
       "      <td>0.1752</td>\n",
       "      <td>0.05533</td>\n",
       "      <td>...</td>\n",
       "      <td>38.25</td>\n",
       "      <td>155.00</td>\n",
       "      <td>1731.0</td>\n",
       "      <td>0.11660</td>\n",
       "      <td>0.19220</td>\n",
       "      <td>0.3215</td>\n",
       "      <td>0.1628</td>\n",
       "      <td>0.2572</td>\n",
       "      <td>0.06637</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>566</th>\n",
       "      <td>16.60</td>\n",
       "      <td>28.08</td>\n",
       "      <td>108.30</td>\n",
       "      <td>858.1</td>\n",
       "      <td>0.08455</td>\n",
       "      <td>0.10230</td>\n",
       "      <td>0.09251</td>\n",
       "      <td>0.05302</td>\n",
       "      <td>0.1590</td>\n",
       "      <td>0.05648</td>\n",
       "      <td>...</td>\n",
       "      <td>34.12</td>\n",
       "      <td>126.70</td>\n",
       "      <td>1124.0</td>\n",
       "      <td>0.11390</td>\n",
       "      <td>0.30940</td>\n",
       "      <td>0.3403</td>\n",
       "      <td>0.1418</td>\n",
       "      <td>0.2218</td>\n",
       "      <td>0.07820</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>567</th>\n",
       "      <td>20.60</td>\n",
       "      <td>29.33</td>\n",
       "      <td>140.10</td>\n",
       "      <td>1265.0</td>\n",
       "      <td>0.11780</td>\n",
       "      <td>0.27700</td>\n",
       "      <td>0.35140</td>\n",
       "      <td>0.15200</td>\n",
       "      <td>0.2397</td>\n",
       "      <td>0.07016</td>\n",
       "      <td>...</td>\n",
       "      <td>39.42</td>\n",
       "      <td>184.60</td>\n",
       "      <td>1821.0</td>\n",
       "      <td>0.16500</td>\n",
       "      <td>0.86810</td>\n",
       "      <td>0.9387</td>\n",
       "      <td>0.2650</td>\n",
       "      <td>0.4087</td>\n",
       "      <td>0.12400</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>568</th>\n",
       "      <td>7.76</td>\n",
       "      <td>24.54</td>\n",
       "      <td>47.92</td>\n",
       "      <td>181.0</td>\n",
       "      <td>0.05263</td>\n",
       "      <td>0.04362</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.1587</td>\n",
       "      <td>0.05884</td>\n",
       "      <td>...</td>\n",
       "      <td>30.37</td>\n",
       "      <td>59.16</td>\n",
       "      <td>268.6</td>\n",
       "      <td>0.08996</td>\n",
       "      <td>0.06444</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.2871</td>\n",
       "      <td>0.07039</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>569 rows × 31 columns</p>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "execution_count": 2
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "source": [
    "import pandas as pd\r\n",
    "# pandas可以读取网络上的数据\r\n",
    "df = pd.read_csv(r'https://labfile.oss.aliyuncs.com/courses/2534/breast_cancer.csv')\r\n",
    "df"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "     mean radius  mean texture  mean perimeter  mean area  mean smoothness  \\\n",
       "0          17.99         10.38          122.80     1001.0          0.11840   \n",
       "1          20.57         17.77          132.90     1326.0          0.08474   \n",
       "2          19.69         21.25          130.00     1203.0          0.10960   \n",
       "3          11.42         20.38           77.58      386.1          0.14250   \n",
       "4          20.29         14.34          135.10     1297.0          0.10030   \n",
       "..           ...           ...             ...        ...              ...   \n",
       "564        21.56         22.39          142.00     1479.0          0.11100   \n",
       "565        20.13         28.25          131.20     1261.0          0.09780   \n",
       "566        16.60         28.08          108.30      858.1          0.08455   \n",
       "567        20.60         29.33          140.10     1265.0          0.11780   \n",
       "568         7.76         24.54           47.92      181.0          0.05263   \n",
       "\n",
       "     mean compactness  mean concavity  mean concave points  mean symmetry  \\\n",
       "0             0.27760         0.30010              0.14710         0.2419   \n",
       "1             0.07864         0.08690              0.07017         0.1812   \n",
       "2             0.15990         0.19740              0.12790         0.2069   \n",
       "3             0.28390         0.24140              0.10520         0.2597   \n",
       "4             0.13280         0.19800              0.10430         0.1809   \n",
       "..                ...             ...                  ...            ...   \n",
       "564           0.11590         0.24390              0.13890         0.1726   \n",
       "565           0.10340         0.14400              0.09791         0.1752   \n",
       "566           0.10230         0.09251              0.05302         0.1590   \n",
       "567           0.27700         0.35140              0.15200         0.2397   \n",
       "568           0.04362         0.00000              0.00000         0.1587   \n",
       "\n",
       "     mean fractal dimension  ...  worst texture  worst perimeter  worst area  \\\n",
       "0                   0.07871  ...          17.33           184.60      2019.0   \n",
       "1                   0.05667  ...          23.41           158.80      1956.0   \n",
       "2                   0.05999  ...          25.53           152.50      1709.0   \n",
       "3                   0.09744  ...          26.50            98.87       567.7   \n",
       "4                   0.05883  ...          16.67           152.20      1575.0   \n",
       "..                      ...  ...            ...              ...         ...   \n",
       "564                 0.05623  ...          26.40           166.10      2027.0   \n",
       "565                 0.05533  ...          38.25           155.00      1731.0   \n",
       "566                 0.05648  ...          34.12           126.70      1124.0   \n",
       "567                 0.07016  ...          39.42           184.60      1821.0   \n",
       "568                 0.05884  ...          30.37            59.16       268.6   \n",
       "\n",
       "     worst smoothness  worst compactness  worst concavity  \\\n",
       "0             0.16220            0.66560           0.7119   \n",
       "1             0.12380            0.18660           0.2416   \n",
       "2             0.14440            0.42450           0.4504   \n",
       "3             0.20980            0.86630           0.6869   \n",
       "4             0.13740            0.20500           0.4000   \n",
       "..                ...                ...              ...   \n",
       "564           0.14100            0.21130           0.4107   \n",
       "565           0.11660            0.19220           0.3215   \n",
       "566           0.11390            0.30940           0.3403   \n",
       "567           0.16500            0.86810           0.9387   \n",
       "568           0.08996            0.06444           0.0000   \n",
       "\n",
       "     worst concave points  worst symmetry  worst fractal dimension  target  \n",
       "0                  0.2654          0.4601                  0.11890       0  \n",
       "1                  0.1860          0.2750                  0.08902       0  \n",
       "2                  0.2430          0.3613                  0.08758       0  \n",
       "3                  0.2575          0.6638                  0.17300       0  \n",
       "4                  0.1625          0.2364                  0.07678       0  \n",
       "..                    ...             ...                      ...     ...  \n",
       "564                0.2216          0.2060                  0.07115       0  \n",
       "565                0.1628          0.2572                  0.06637       0  \n",
       "566                0.1418          0.2218                  0.07820       0  \n",
       "567                0.2650          0.4087                  0.12400       0  \n",
       "568                0.0000          0.2871                  0.07039       1  \n",
       "\n",
       "[569 rows x 31 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mean radius</th>\n",
       "      <th>mean texture</th>\n",
       "      <th>mean perimeter</th>\n",
       "      <th>mean area</th>\n",
       "      <th>mean smoothness</th>\n",
       "      <th>mean compactness</th>\n",
       "      <th>mean concavity</th>\n",
       "      <th>mean concave points</th>\n",
       "      <th>mean symmetry</th>\n",
       "      <th>mean fractal dimension</th>\n",
       "      <th>...</th>\n",
       "      <th>worst texture</th>\n",
       "      <th>worst perimeter</th>\n",
       "      <th>worst area</th>\n",
       "      <th>worst smoothness</th>\n",
       "      <th>worst compactness</th>\n",
       "      <th>worst concavity</th>\n",
       "      <th>worst concave points</th>\n",
       "      <th>worst symmetry</th>\n",
       "      <th>worst fractal dimension</th>\n",
       "      <th>target</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>17.99</td>\n",
       "      <td>10.38</td>\n",
       "      <td>122.80</td>\n",
       "      <td>1001.0</td>\n",
       "      <td>0.11840</td>\n",
       "      <td>0.27760</td>\n",
       "      <td>0.30010</td>\n",
       "      <td>0.14710</td>\n",
       "      <td>0.2419</td>\n",
       "      <td>0.07871</td>\n",
       "      <td>...</td>\n",
       "      <td>17.33</td>\n",
       "      <td>184.60</td>\n",
       "      <td>2019.0</td>\n",
       "      <td>0.16220</td>\n",
       "      <td>0.66560</td>\n",
       "      <td>0.7119</td>\n",
       "      <td>0.2654</td>\n",
       "      <td>0.4601</td>\n",
       "      <td>0.11890</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20.57</td>\n",
       "      <td>17.77</td>\n",
       "      <td>132.90</td>\n",
       "      <td>1326.0</td>\n",
       "      <td>0.08474</td>\n",
       "      <td>0.07864</td>\n",
       "      <td>0.08690</td>\n",
       "      <td>0.07017</td>\n",
       "      <td>0.1812</td>\n",
       "      <td>0.05667</td>\n",
       "      <td>...</td>\n",
       "      <td>23.41</td>\n",
       "      <td>158.80</td>\n",
       "      <td>1956.0</td>\n",
       "      <td>0.12380</td>\n",
       "      <td>0.18660</td>\n",
       "      <td>0.2416</td>\n",
       "      <td>0.1860</td>\n",
       "      <td>0.2750</td>\n",
       "      <td>0.08902</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>19.69</td>\n",
       "      <td>21.25</td>\n",
       "      <td>130.00</td>\n",
       "      <td>1203.0</td>\n",
       "      <td>0.10960</td>\n",
       "      <td>0.15990</td>\n",
       "      <td>0.19740</td>\n",
       "      <td>0.12790</td>\n",
       "      <td>0.2069</td>\n",
       "      <td>0.05999</td>\n",
       "      <td>...</td>\n",
       "      <td>25.53</td>\n",
       "      <td>152.50</td>\n",
       "      <td>1709.0</td>\n",
       "      <td>0.14440</td>\n",
       "      <td>0.42450</td>\n",
       "      <td>0.4504</td>\n",
       "      <td>0.2430</td>\n",
       "      <td>0.3613</td>\n",
       "      <td>0.08758</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>11.42</td>\n",
       "      <td>20.38</td>\n",
       "      <td>77.58</td>\n",
       "      <td>386.1</td>\n",
       "      <td>0.14250</td>\n",
       "      <td>0.28390</td>\n",
       "      <td>0.24140</td>\n",
       "      <td>0.10520</td>\n",
       "      <td>0.2597</td>\n",
       "      <td>0.09744</td>\n",
       "      <td>...</td>\n",
       "      <td>26.50</td>\n",
       "      <td>98.87</td>\n",
       "      <td>567.7</td>\n",
       "      <td>0.20980</td>\n",
       "      <td>0.86630</td>\n",
       "      <td>0.6869</td>\n",
       "      <td>0.2575</td>\n",
       "      <td>0.6638</td>\n",
       "      <td>0.17300</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20.29</td>\n",
       "      <td>14.34</td>\n",
       "      <td>135.10</td>\n",
       "      <td>1297.0</td>\n",
       "      <td>0.10030</td>\n",
       "      <td>0.13280</td>\n",
       "      <td>0.19800</td>\n",
       "      <td>0.10430</td>\n",
       "      <td>0.1809</td>\n",
       "      <td>0.05883</td>\n",
       "      <td>...</td>\n",
       "      <td>16.67</td>\n",
       "      <td>152.20</td>\n",
       "      <td>1575.0</td>\n",
       "      <td>0.13740</td>\n",
       "      <td>0.20500</td>\n",
       "      <td>0.4000</td>\n",
       "      <td>0.1625</td>\n",
       "      <td>0.2364</td>\n",
       "      <td>0.07678</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>564</th>\n",
       "      <td>21.56</td>\n",
       "      <td>22.39</td>\n",
       "      <td>142.00</td>\n",
       "      <td>1479.0</td>\n",
       "      <td>0.11100</td>\n",
       "      <td>0.11590</td>\n",
       "      <td>0.24390</td>\n",
       "      <td>0.13890</td>\n",
       "      <td>0.1726</td>\n",
       "      <td>0.05623</td>\n",
       "      <td>...</td>\n",
       "      <td>26.40</td>\n",
       "      <td>166.10</td>\n",
       "      <td>2027.0</td>\n",
       "      <td>0.14100</td>\n",
       "      <td>0.21130</td>\n",
       "      <td>0.4107</td>\n",
       "      <td>0.2216</td>\n",
       "      <td>0.2060</td>\n",
       "      <td>0.07115</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>565</th>\n",
       "      <td>20.13</td>\n",
       "      <td>28.25</td>\n",
       "      <td>131.20</td>\n",
       "      <td>1261.0</td>\n",
       "      <td>0.09780</td>\n",
       "      <td>0.10340</td>\n",
       "      <td>0.14400</td>\n",
       "      <td>0.09791</td>\n",
       "      <td>0.1752</td>\n",
       "      <td>0.05533</td>\n",
       "      <td>...</td>\n",
       "      <td>38.25</td>\n",
       "      <td>155.00</td>\n",
       "      <td>1731.0</td>\n",
       "      <td>0.11660</td>\n",
       "      <td>0.19220</td>\n",
       "      <td>0.3215</td>\n",
       "      <td>0.1628</td>\n",
       "      <td>0.2572</td>\n",
       "      <td>0.06637</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>566</th>\n",
       "      <td>16.60</td>\n",
       "      <td>28.08</td>\n",
       "      <td>108.30</td>\n",
       "      <td>858.1</td>\n",
       "      <td>0.08455</td>\n",
       "      <td>0.10230</td>\n",
       "      <td>0.09251</td>\n",
       "      <td>0.05302</td>\n",
       "      <td>0.1590</td>\n",
       "      <td>0.05648</td>\n",
       "      <td>...</td>\n",
       "      <td>34.12</td>\n",
       "      <td>126.70</td>\n",
       "      <td>1124.0</td>\n",
       "      <td>0.11390</td>\n",
       "      <td>0.30940</td>\n",
       "      <td>0.3403</td>\n",
       "      <td>0.1418</td>\n",
       "      <td>0.2218</td>\n",
       "      <td>0.07820</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>567</th>\n",
       "      <td>20.60</td>\n",
       "      <td>29.33</td>\n",
       "      <td>140.10</td>\n",
       "      <td>1265.0</td>\n",
       "      <td>0.11780</td>\n",
       "      <td>0.27700</td>\n",
       "      <td>0.35140</td>\n",
       "      <td>0.15200</td>\n",
       "      <td>0.2397</td>\n",
       "      <td>0.07016</td>\n",
       "      <td>...</td>\n",
       "      <td>39.42</td>\n",
       "      <td>184.60</td>\n",
       "      <td>1821.0</td>\n",
       "      <td>0.16500</td>\n",
       "      <td>0.86810</td>\n",
       "      <td>0.9387</td>\n",
       "      <td>0.2650</td>\n",
       "      <td>0.4087</td>\n",
       "      <td>0.12400</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>568</th>\n",
       "      <td>7.76</td>\n",
       "      <td>24.54</td>\n",
       "      <td>47.92</td>\n",
       "      <td>181.0</td>\n",
       "      <td>0.05263</td>\n",
       "      <td>0.04362</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.1587</td>\n",
       "      <td>0.05884</td>\n",
       "      <td>...</td>\n",
       "      <td>30.37</td>\n",
       "      <td>59.16</td>\n",
       "      <td>268.6</td>\n",
       "      <td>0.08996</td>\n",
       "      <td>0.06444</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.0000</td>\n",
       "      <td>0.2871</td>\n",
       "      <td>0.07039</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>569 rows × 31 columns</p>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "source": [
    "print(df.describe())\r\n",
    "# 尝试分析数据\r\n",
    "import seaborn as sns\r\n",
    "sns.set()\r\n",
    "# 一共有31行，最后一行是目标值01是否患乳腺癌"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "       mean radius  mean texture  mean perimeter    mean area  \\\n",
      "count   569.000000    569.000000      569.000000   569.000000   \n",
      "mean     14.127292     19.289649       91.969033   654.889104   \n",
      "std       3.524049      4.301036       24.298981   351.914129   \n",
      "min       6.981000      9.710000       43.790000   143.500000   \n",
      "25%      11.700000     16.170000       75.170000   420.300000   \n",
      "50%      13.370000     18.840000       86.240000   551.100000   \n",
      "75%      15.780000     21.800000      104.100000   782.700000   \n",
      "max      28.110000     39.280000      188.500000  2501.000000   \n",
      "\n",
      "       mean smoothness  mean compactness  mean concavity  mean concave points  \\\n",
      "count       569.000000        569.000000      569.000000           569.000000   \n",
      "mean          0.096360          0.104341        0.088799             0.048919   \n",
      "std           0.014064          0.052813        0.079720             0.038803   \n",
      "min           0.052630          0.019380        0.000000             0.000000   \n",
      "25%           0.086370          0.064920        0.029560             0.020310   \n",
      "50%           0.095870          0.092630        0.061540             0.033500   \n",
      "75%           0.105300          0.130400        0.130700             0.074000   \n",
      "max           0.163400          0.345400        0.426800             0.201200   \n",
      "\n",
      "       mean symmetry  mean fractal dimension  ...  worst texture  \\\n",
      "count     569.000000              569.000000  ...     569.000000   \n",
      "mean        0.181162                0.062798  ...      25.677223   \n",
      "std         0.027414                0.007060  ...       6.146258   \n",
      "min         0.106000                0.049960  ...      12.020000   \n",
      "25%         0.161900                0.057700  ...      21.080000   \n",
      "50%         0.179200                0.061540  ...      25.410000   \n",
      "75%         0.195700                0.066120  ...      29.720000   \n",
      "max         0.304000                0.097440  ...      49.540000   \n",
      "\n",
      "       worst perimeter   worst area  worst smoothness  worst compactness  \\\n",
      "count       569.000000   569.000000        569.000000         569.000000   \n",
      "mean        107.261213   880.583128          0.132369           0.254265   \n",
      "std          33.602542   569.356993          0.022832           0.157336   \n",
      "min          50.410000   185.200000          0.071170           0.027290   \n",
      "25%          84.110000   515.300000          0.116600           0.147200   \n",
      "50%          97.660000   686.500000          0.131300           0.211900   \n",
      "75%         125.400000  1084.000000          0.146000           0.339100   \n",
      "max         251.200000  4254.000000          0.222600           1.058000   \n",
      "\n",
      "       worst concavity  worst concave points  worst symmetry  \\\n",
      "count       569.000000            569.000000      569.000000   \n",
      "mean          0.272188              0.114606        0.290076   \n",
      "std           0.208624              0.065732        0.061867   \n",
      "min           0.000000              0.000000        0.156500   \n",
      "25%           0.114500              0.064930        0.250400   \n",
      "50%           0.226700              0.099930        0.282200   \n",
      "75%           0.382900              0.161400        0.317900   \n",
      "max           1.252000              0.291000        0.663800   \n",
      "\n",
      "       worst fractal dimension      target  \n",
      "count               569.000000  569.000000  \n",
      "mean                  0.083946    0.627417  \n",
      "std                   0.018061    0.483918  \n",
      "min                   0.055040    0.000000  \n",
      "25%                   0.071460    0.000000  \n",
      "50%                   0.080040    1.000000  \n",
      "75%                   0.092080    1.000000  \n",
      "max                   0.207500    1.000000  \n",
      "\n",
      "[8 rows x 31 columns]\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "可以看到该数据集合一共有 569 条数据，每条数据有 30 个和乳腺癌相关的病变特征，最后一列是该患者是否患有乳腺癌的诊断结果。其中 0 表示没有患有乳腺癌，1 表示患有乳腺癌。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "我们可以利用 pandas 中的切片，先将上表中的特征和标签分开："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "source": [
    "# 先把特征和标签分开,也就是把最后一列和前面的列分开，分别作为X和Y\r\n",
    "X = df[df.columns[0:-1]].to_numpy()\r\n",
    "y = df[df.columns[-1]].to_numpy()\r\n",
    "X.shape, y.shape"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "((569, 30), (569,))"
      ]
     },
     "metadata": {},
     "execution_count": 4
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "source": [
    "df.columns\r\n",
    "# 返回df的所有的列的标签\r\n",
    "X = df[df.columns[0:-1]].to_numpy()\r\n",
    "y = df[df.columns[-1]].to_numpy()\r\n",
    "# 然后按标签进行切片（这就是对列进行切片了），然后再按标签进行索引，就完成了\r\n",
    "\r\n",
    "# 先转换成numppy再切片也可以\r\n",
    "# 但是要注意维度，是对列进行切片在第1维度上，还是先切片再转换成numpy好\r\n",
    "X = df.to_numpy()[:,:-1]\r\n",
    "y = df.to_numpy()[:,-1]\r\n",
    "X.shape, y.shape"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "((569, 30), (569,))"
      ]
     },
     "metadata": {},
     "execution_count": 5
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "可以看到共有 569 条数据，每条数据有 30 个特征和 1 个标签。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 数据集的划分和标准化"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "为了能够评价模型的好坏，这里我们利用 `sklearn.model_selection` 函数，将原数据按比例随机分为训练数据集和测试数据集，如下："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "source": [
    "from sklearn.model_selection import train_test_split\r\n",
    "# 按照 0.8 和 0.2 的比例随机划分数据集合\r\n",
    "X_train, X_test, y_train, y_test = train_test_split(\r\n",
    "    X, y, test_size=0.2, random_state=1234)\r\n",
    "X_train.shape, y_train.shape, X_test.shape, y_test.shape"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "((455, 30), (455,), (114, 30), (114,))"
      ]
     },
     "metadata": {},
     "execution_count": 5
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "source": [
    "# 使用sklearn来进行数据的切分\r\n",
    "from sklearn.model_selection import train_test_split\r\n",
    "# 按照0.8比0.2的比例进行随机划分数据\r\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234)\r\n",
    "# 注意这个train_test_split是以train test train test的方式返回的\r\n",
    "X_train.shape,y_train.shape,X_test.shape,y_test.shape"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "((455, 30), (455,), (114, 30), (114,))"
      ]
     },
     "metadata": {},
     "execution_count": 6
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "为了加快模型的收敛速度，一般我们都需要对原始数据进行标准化处理，将所有的数据按照比例缩放到一定范围内。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "这里我们可以使用 `sklearn.preprocessing` 来对数据集合进行标准化。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "source": [
    "# 进行标准化处理\r\n",
    "from sklearn.preprocessing import StandardScaler\r\n",
    "sc = StandardScaler()\r\n",
    "# 对特征进行标准化，标签不要标准化，因为标签只有 0 和 1\r\n",
    "X_train = sc.fit_transform(X_train)\r\n",
    "X_test = sc.transform(X_test)\r\n",
    "X_train"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[-0.36180827, -0.26521011, -0.31715702, ..., -0.07967528,\n",
       "        -0.52798733,  0.2506337 ],\n",
       "       [-0.8632675 ,  0.71560604, -0.85646012, ..., -0.76980239,\n",
       "         0.44312729, -0.20987332],\n",
       "       [-0.4334453 ,  0.32513895, -0.41286667, ..., -0.06601541,\n",
       "        -1.1169427 ,  0.0329492 ],\n",
       "       ...,\n",
       "       [-0.479293  , -0.17689018, -0.45697634, ..., -0.20261414,\n",
       "         0.18670009,  0.17414996],\n",
       "       [ 1.16835876, -0.15364809,  1.17466524, ...,  0.26789258,\n",
       "         0.19828067, -0.23394164],\n",
       "       [-0.40765597, -1.29715887, -0.42826344, ..., -0.78042674,\n",
       "        -0.88036793, -0.80355834]])"
      ]
     },
     "metadata": {},
     "execution_count": 7
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "source": [
    "# 进行标准化处理\r\n",
    "from sklearn.preprocessing import StandardScaler\r\n",
    "# StandardScaler()\r\n",
    "# z = (x - u) / s\r\n",
    "# 先实例化standardscaler\r\n",
    "sc = StandardScaler()\r\n",
    "# 一般来说对训练数据进行fit_transform，对测试数据进行transform\r\n",
    "X_train = sc.fit_transform(X_train)\r\n",
    "X_test = sc.transform(X_test)\r\n",
    "X_train"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[-0.36180827, -0.26521011, -0.31715702, ..., -0.07967528,\n",
       "        -0.52798733,  0.2506337 ],\n",
       "       [-0.8632675 ,  0.71560604, -0.85646012, ..., -0.76980239,\n",
       "         0.44312729, -0.20987332],\n",
       "       [-0.4334453 ,  0.32513895, -0.41286667, ..., -0.06601541,\n",
       "        -1.1169427 ,  0.0329492 ],\n",
       "       ...,\n",
       "       [-0.479293  , -0.17689018, -0.45697634, ..., -0.20261414,\n",
       "         0.18670009,  0.17414996],\n",
       "       [ 1.16835876, -0.15364809,  1.17466524, ...,  0.26789258,\n",
       "         0.19828067, -0.23394164],\n",
       "       [-0.40765597, -1.29715887, -0.42826344, ..., -0.78042674,\n",
       "        -0.88036793, -0.80355834]])"
      ]
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "最后，为了将数据放入 PyTorch 定义的模型之中，我们必须将所有的数据转为 张量类型："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "source": [
    "import torch\r\n",
    "import numpy as np\r\n",
    "\r\n",
    "X_train = torch.from_numpy(X_train.astype(np.float32))\r\n",
    "X_test = torch.from_numpy(X_test.astype(np.float32))\r\n",
    "y_train = torch.from_numpy(y_train.astype(np.float32))\r\n",
    "y_test = torch.from_numpy(y_test.astype(np.float32))\r\n",
    "\r\n",
    "# 将标签也转为 2 维，否则放入模型之中训练时，可能出错\r\n",
    "y_train = y_train.view(y_train.shape[0], 1)\r\n",
    "y_test = y_test.view(y_test.shape[0], 1)\r\n",
    "X_train.size(), y_train.size()"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "(torch.Size([455, 30]), torch.Size([455, 1]))"
      ]
     },
     "metadata": {},
     "execution_count": 8
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 转换为tensor\r\n",
    "# 先把numpy转换为32位float然后再转换成tensor\r\n",
    "import torch\r\n",
    "import torch.nn as nn\r\n",
    "\r\n",
    "X_train = torch.from_numpy(X_train.astype(np.float32))\r\n",
    "X_test = torch.from_numpy(X_test.astype(np.float32))\r\n",
    "# 标签也要转换，而且还要reshap成二维的\r\n",
    "y_train = torch.from_numpy(y_train.astype(np.float32).reshape(-1,1))\r\n",
    "y_test = torch.from_numpy(y_test.astype(np.float32).reshape(-1,1))"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 乳腺癌的预测"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 模型的定义"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "在处理完数据后，接下来，我们就需要建立相应的模型，用于乳腺癌的预测了。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "线性函数是一条没有上界和下界的直线，即线性函数预测出来的值可以很大如 112321442，也可以很小如 -1231242412。而本实验的数据标签只有 0（患病） 或 1（不患病），因此用线性函数来拟合乳腺癌的数据点是不合理的。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "我们需要找到输出始终为 0-1 之间的函数模型。如果拥有这样的函数模型，那么将任意 x 放入该模型中，都会输出一个 0-1 之间的值。这个值我们可以看做是患有乳腺癌的概率。如果这个概率值小于 0.5 则表示没有患乳腺癌。如果这个概率值大于 0.5 则表示患有乳腺癌。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "逻辑回归函数 Sigmoid 就是这样一种函数，该函数又叫做激活函数，公式如下： "
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "$$\\sigma = \\frac{1}{1+e^{-z}}$$"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "该函数的几何形式如下所示："
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "<img width=\"400px\" src=\"https://doc.shiyanlou.com/courses/2534/1166617/d3267547f64d893dfb1fb73ecd80a879-0\">"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "从图中我们可以看出，该函数就是一个上下界分别为 1 和 0  的有界非线性函数。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "我们可以让通过了线性函数的输出，再通过一次上面的激活函数，进而得到 0-1 之间的结果。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "综上，乳腺癌的预测模型如下："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "source": [
    "import torch.nn as nn\r\n",
    "# 我们的模型是一个线性函数+激活函数的非线性模型\r\n",
    "# modle(x) = sigmoid(w*x+b)\r\n",
    "\r\n",
    "\r\n",
    "class Model(nn.Module):\r\n",
    "    def __init__(self, n_input_features):\r\n",
    "        super(Model, self).__init__()\r\n",
    "        self.linear = nn.Linear(n_input_features, 1)\r\n",
    "\r\n",
    "    def forward(self, x):\r\n",
    "        # torch 中已经定义了 sigmoid 函数模型\r\n",
    "        y_pred = torch.sigmoid(self.linear(x))\r\n",
    "        return y_pred\r\n",
    "\r\n",
    "\r\n",
    "# 获得样本量和特征数\r\n",
    "n_samples, n_features = X.shape\r\n",
    "# 模型的初始化\r\n",
    "model = Model(n_features)\r\n",
    "model"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Model(\n",
       "  (linear): Linear(in_features=30, out_features=1, bias=True)\n",
       ")"
      ]
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "source": [
    "import torch\r\n",
    "import torch.nn as nn\r\n",
    "\r\n",
    "class MyModel(nn.Module):\r\n",
    "    # 这里初始化需要的层\r\n",
    "    def __init__(self,in_features,out_features):\r\n",
    "        super(MyModel, self).__init__()\r\n",
    "        self.linear = nn.Linear(in_features = in_features, out_features = out_features)\r\n",
    "\r\n",
    "    # 这里定义前向传播\r\n",
    "    def forward(self,x):\r\n",
    "        # 前向传播再过激活函数\r\n",
    "        # 激活函数只是一个函数，因此并不需要初始化\r\n",
    "        return torch.sigmoid(self.linear(x))\r\n",
    "in_features,out_features = 1,1\r\n",
    "my_model = MyModel(in_features,out_features)\r\n",
    "my_model"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "MyModel(\n",
       "  (linear): Linear(in_features=1, out_features=1, bias=True)\n",
       ")"
      ]
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "至此，我们就得到了一个乳腺癌的初始模型。由于最后通过了一层逻辑回归函数，无论输入的值为多少，模型的输出都必定属于 0-1 之间。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 损失函数和优化器"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "接下来的步骤和上个实验中的步骤类似。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "首先，让我们来定义一下损失函数，由于我们的标签只有 0 和 1，因此这里使用二元交叉熵损失来计算真实值和预测值之间的距离了。该损失函数的公式如下："
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "$$L = -\\sum_{i=1}^N y^i log \\hat{y}^i + (1-y^i)log(1-\\hat{y}^i)$$"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "当然，我们不必手写上面的损失函数， 直接使用  `nn.BCELoss()` 即可："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "source": [
    "# 损失和优化器的定义\r\n",
    "# 迭代次数\r\n",
    "num_epochs = 100\r\n",
    "# 学习率\r\n",
    "learning_rate = 0.01\r\n",
    "# 二元交叉熵损失\r\n",
    "criterion = nn.BCELoss()\r\n",
    "# SGD 优化器\r\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)\r\n",
    "criterion, optimizer"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "(BCELoss(),\n",
       " SGD (\n",
       " Parameter Group 0\n",
       "     dampening: 0\n",
       "     lr: 0.01\n",
       "     momentum: 0\n",
       "     nesterov: False\n",
       "     weight_decay: 0\n",
       " ))"
      ]
     },
     "metadata": {},
     "execution_count": 18
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "source": [
    "# 使用二元交叉熵来作为二分类问题的loss\r\n",
    "# 迭代次数\r\n",
    "epochs = 100\r\n",
    "# 学习率\r\n",
    "learning_rate = 0.01\r\n",
    "# 二元交叉熵\r\n",
    "criterion = nn.BCELoss()\r\n",
    "# 优化器\r\n",
    "optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate)\r\n",
    "criterion,optimizer"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "(BCELoss(),\n",
       " SGD (\n",
       " Parameter Group 0\n",
       "     dampening: 0\n",
       "     lr: 0.01\n",
       "     momentum: 0\n",
       "     nesterov: False\n",
       "     weight_decay: 0\n",
       " ))"
      ]
     },
     "metadata": {},
     "execution_count": 17
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 模型的训练"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    " 定义完损失函数和优化器后，接下来的模型训练步骤就是固定的了，如下："
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "- 通过模型的正向传播，输出预测结果。\n",
    "- 通过预测结果和真实标签计算损失。\n",
    "- 通过后向传播，获得梯度。\n",
    "- 通过梯度更新模型的权重。\n",
    "- 进行梯度的清空。\n",
    "- 循环上面操作，直到损失较小为止。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "让我们用代码完成上面的步骤："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "source": [
    "for epoch in range(num_epochs):\r\n",
    "    y_pred = model(X_train)\r\n",
    "    loss = criterion(y_pred, y_train)\r\n",
    "    # 后向传播、梯度更新、梯度清空\r\n",
    "    loss.backward()\r\n",
    "    optimizer.step()\r\n",
    "    optimizer.zero_grad()\r\n",
    "\r\n",
    "    if (epoch+1) % 10 == 0:\r\n",
    "        print(f'epoch: {epoch+1}, loss = {loss.item():.4f}')\r\n",
    "print(\"模型训练完毕！！\")"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "epoch: 10, loss = 0.6135\n",
      "epoch: 20, loss = 0.4957\n",
      "epoch: 30, loss = 0.4247\n",
      "epoch: 40, loss = 0.3773\n",
      "epoch: 50, loss = 0.3431\n",
      "epoch: 60, loss = 0.3169\n",
      "epoch: 70, loss = 0.2960\n",
      "epoch: 80, loss = 0.2789\n",
      "epoch: 90, loss = 0.2645\n",
      "epoch: 100, loss = 0.2521\n",
      "模型训练完毕！！\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "source": [
    "for epoch in range(epochs):\r\n",
    "    # 前向传播\r\n",
    "    y_pred = model(X_train)\r\n",
    "    # 计算损失,y_pred要放在y_train的前面\r\n",
    "    loss = criterion(y_pred,y_train)\r\n",
    "    # 反向传播\r\n",
    "    loss.backward()\r\n",
    "    # 更新参数\r\n",
    "    optimizer.step()\r\n",
    "    # 清空梯度\r\n",
    "    optimizer.zero_grad()\r\n",
    "\r\n",
    "    # 打印loss \r\n",
    "    if epoch%2==0:\r\n",
    "        print(f'epoch{epoch:<3}, loss{loss:.4f}')\r\n",
    "print('训练结束')"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "epoch0  , loss0.1822\n",
      "epoch2  , loss0.1814\n",
      "epoch4  , loss0.1805\n",
      "epoch6  , loss0.1797\n",
      "epoch8  , loss0.1789\n",
      "epoch10 , loss0.1781\n",
      "epoch12 , loss0.1773\n",
      "epoch14 , loss0.1765\n",
      "epoch16 , loss0.1757\n",
      "epoch18 , loss0.1750\n",
      "epoch20 , loss0.1742\n",
      "epoch22 , loss0.1735\n",
      "epoch24 , loss0.1727\n",
      "epoch26 , loss0.1720\n",
      "epoch28 , loss0.1713\n",
      "epoch30 , loss0.1706\n",
      "epoch32 , loss0.1699\n",
      "epoch34 , loss0.1692\n",
      "epoch36 , loss0.1685\n",
      "epoch38 , loss0.1678\n",
      "epoch40 , loss0.1672\n",
      "epoch42 , loss0.1665\n",
      "epoch44 , loss0.1658\n",
      "epoch46 , loss0.1652\n",
      "epoch48 , loss0.1646\n",
      "epoch50 , loss0.1639\n",
      "epoch52 , loss0.1633\n",
      "epoch54 , loss0.1627\n",
      "epoch56 , loss0.1621\n",
      "epoch58 , loss0.1615\n",
      "epoch60 , loss0.1609\n",
      "epoch62 , loss0.1603\n",
      "epoch64 , loss0.1597\n",
      "epoch66 , loss0.1592\n",
      "epoch68 , loss0.1586\n",
      "epoch70 , loss0.1580\n",
      "epoch72 , loss0.1575\n",
      "epoch74 , loss0.1569\n",
      "epoch76 , loss0.1564\n",
      "epoch78 , loss0.1558\n",
      "epoch80 , loss0.1553\n",
      "epoch82 , loss0.1548\n",
      "epoch84 , loss0.1543\n",
      "epoch86 , loss0.1537\n",
      "epoch88 , loss0.1532\n",
      "epoch90 , loss0.1527\n",
      "epoch92 , loss0.1522\n",
      "epoch94 , loss0.1517\n",
      "epoch96 , loss0.1512\n",
      "epoch98 , loss0.1508\n",
      "训练结束\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "综上，我们训练好了一个乳腺癌的预测模型。我们可以尝试对任意一条数据进行预测："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "source": [
    "index = np.random.randint(0, len(X_test))\r\n",
    "y_predicted = model(X_test[index])\r\n",
    "# 小于 0.5 则输出 0 ，大于0.5 则输出 1\r\n",
    "y_predicted_cls = y_predicted.round()\r\n",
    "\r\n",
    "# 将结果转为 numpy类型\r\n",
    "real = y_test[index].detach().numpy()[0]\r\n",
    "predict = y_predicted_cls.detach().numpy()[0]\r\n",
    "print(\"第 {} 条测试数据的真实结果为 {} ，预测结果为 {} \"\r\n",
    "      .format(index, real, predict))"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "第 78 条测试数据的真实结果为 1.0 ，预测结果为 1.0 \n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "source": [
    "# 来预测一下呢\r\n",
    "index = np.random.randint(0,len(X_test))\r\n",
    "# 随机取一个index的值\r\n",
    "y_predicted = model(X_test[index])\r\n",
    "# 取整小于0.5为0大于0.5为1\r\n",
    "# y_predicted_label = y_predicted.round()\r\n",
    "real = y_test[index]\r\n",
    "print(f'第{index:}条数据，预测的结果为{y_predicted[0]:.3f},真实结果为{real[0]:}')"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "第94条数据，预测的结果为0.024,真实结果为0.0\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "由于模型准确率不是 100%，因此，上面的预测结果和真实结果也可能会不相同。但是，你多运行几次上面代码，必定会出现预测结果和真实结果相同的情况。 "
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "那么，我们训练出来的模型准确率到底是多少呢？"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "source": [
    "# 来看下模型的准确率\r\n",
    "with torch.no_grad():\r\n",
    "    y_predicted = model(X_test)\r\n",
    "    y_predicted_cls = y_predicted.round()\r\n",
    "    acc = y_predicted_cls.eq(y_test).sum().numpy() / float(y_test.shape[0])\r\n",
    "    print(f'accuracy: {acc.item():.4f}')"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "accuracy: 0.9123\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "source": [
    "# 进行预测不需要构建计算图\r\n",
    "with torch.no_grad():\r\n",
    "    y_predicted = model(X_test)\r\n",
    "    y_predicted_cls = y_predicted.round()\r\n",
    "    acc = y_predicted_cls.eq(y_test).sum().numpy() / float(y_test.shape[0])\r\n",
    "    print(f'accuracy: {acc.item():.4f}')"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "accuracy: 0.9123\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "我们利用测试数据，计算出了整个模型的预测准确率大概在 90% 左右，证明我们的模型可以很好地进行乳腺癌的诊断预测。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 实验总结"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "本实验以乳腺癌的预测为例，引入了激活函数 sigmoid 的概念。建立了一个简单的非线性模型用于诊断患者是否患有乳腺癌。其实，本实验建立的一个线性函数+激活函数的模型就是一个简单的神经网络模型。全连接神经网络的实质其实就是无数个线性函数和非线性网络组成的集合。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "<hr><div style=\"color: #999; font-size: 12px;\"><i class=\"fa fa-copyright\" aria-hidden=\"true\"> 本课程内容版权归蓝桥云课所有，禁止转载、下载及非法传播。</i></div>"
   ],
   "metadata": {}
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.8.0 64-bit ('pytorch': conda)"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.0"
  },
  "interpreter": {
   "hash": "95edf26445b41d81dc60008cc593bb3c243ca80a3a822915e2b6f7013280bc10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}